package com.ry.novel.service.impl;

import com.ry.novel.service.BookService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ry.novel.enums.ResponseStatus;
import com.ry.novel.exception.BusinessException;
import com.ry.novel.mapper.BookMapper;
import com.ry.novel.mapper.CategoryMapper;
import com.ry.novel.model.dto.BookInfo;
import com.ry.novel.model.dto.condition.BookQuery;
import com.ry.novel.model.entity.Book;
import com.ry.novel.model.entity.Category;
import com.ry.novel.utils.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.jni.Local;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author ry
 * @since 2022-03-22 21:44
 **/
@Service
@Slf4j
public class BookServiceImpl implements BookService {

    @Autowired
    private BookMapper bookMapper;

    @Autowired
    private CategoryMapper categoryMapper;

    /**
     * 分页查询小说接口
     *
     * @param bookQuery
     * @return
     */
    @Override
    public Page<BookInfo> searchByPage(BookQuery bookQuery) {
        Page<Book> entityPage = new Page<>(bookQuery.getPage(), bookQuery.getSize());
        Page<BookInfo> infoPage = new Page<>(bookQuery.getPage(), bookQuery.getSize());
        QueryWrapper<Book> wrapper = new QueryWrapper<>();
        //查询字数大于0的，大于0的说明发表过章节
        //在后台的话，应该不需要加这限制。
        //wrapper.gt("word_count",0);

        if (null != bookQuery.getBookName()) {
            wrapper.like("book_name", bookQuery.getBookName());
        }

        if (null != bookQuery.getChannel()) {
            wrapper.eq("channel", bookQuery.getChannel());
        }
        if (null != bookQuery.getBookState()) {
            wrapper.eq("book_state", bookQuery.getBookState());
        }
        if (null != bookQuery.getCategoryId()) {
            wrapper.eq("category_id", bookQuery.getCategoryId());
        }

        //总字数,0 三十万字以下 1 三十到五十万字 2 五十到一百万字 3 一百万字以上
        if (null != bookQuery.getWordCount()) {
            switch (bookQuery.getWordCount()) {
                case 0:
                    wrapper.lt("word_count", 30 * 10000);
                    break;
                case 1:
                    wrapper.gt("word_count", 30 * 10000);
                    wrapper.lt("word_count", 50 * 10000);
                    break;
                case 2:
                    wrapper.gt("word_count", 50 * 10000);
                    wrapper.lt("word_count", 100 * 10000);
                    break;
                case 3:
                    wrapper.gt("word_count", 100 * 10000);
                    break;
                default:
                    throw new BusinessException(ResponseStatus.METHOD_PARAM_ERROR);
            }
        }

        //按更新时间筛选
        // 筛选书籍更新时间 0三日内 1七日内 2半月内 3一月内
        if (null != bookQuery.getUpdateTime()) {
            //目标时间
            LocalDateTime targetTime;
            switch (bookQuery.getUpdateTime()) {
                case 0:
                    targetTime = LocalDateTime.now().minusDays(3);
                    break;
                case 1:
                    targetTime = LocalDateTime.now().minusDays(7);
                    break;
                case 2:
                    targetTime = LocalDateTime.now().minusDays(15);
                    break;
                case 3:
                    targetTime = LocalDateTime.now().minusDays(30);
                    break;
                default:
                    throw new BusinessException(ResponseStatus.METHOD_PARAM_ERROR);
            }
            wrapper.gt("update_time", targetTime.toString());
        }

        //选择排序方式 0更新时间 1总字数 2点击量
        if (null != bookQuery.getSortWay()) {
            switch (bookQuery.getSortWay()) {
                case 0:
                    wrapper.orderByDesc("update_time");
                    break;
                case 1:
                    wrapper.orderByDesc("word_count");
                    break;
                case 2:
                    wrapper.orderByDesc("visit_count");
                    break;
                default:
                    throw new BusinessException(ResponseStatus.METHOD_PARAM_ERROR);
            }
        }

        if (null != bookQuery.getKey()) {
            wrapper.like("book_name", bookQuery.getKey())
                    .or()
                    .like("author_name", bookQuery.getKey());
        }

        bookMapper.selectPage(entityPage, wrapper);

        List<BookInfo> bookInfos = entityPage
                .getRecords()
                .stream()
                .map(entity -> getBookInfo(entity))
                .collect(Collectors.toList());

        infoPage.setRecords(bookInfos);
        infoPage.setTotal(entityPage.getTotal());


        return infoPage;
    }

    @Override
    public BookInfo searchById(Long id) {
        Book book = bookMapper.selectById(id);
        return getBookInfo(book);
    }

    @Override
    public BookInfo queryById(Long bookId) {
        Book book = bookMapper.selectById(bookId);

        return getBookInfo(book);
    }

    @Override
    public void addBook(BookInfo info) {
        Book book = new Book();
        book.setPicUrl(info.getPicUrl());
        book.setBookName(info.getBookName());
        book.setAuthorId(info.getAuthorId());
        book.setAuthorName(info.getAuthorName());
        book.setCategoryId(info.getCategoryId());
        book.setCategoryName(info.getCategoryName());
        book.setBookDesc(info.getBookDesc());
        book.setState(info.getState());
        book.setBookState(info.getBookState());
        book.setVisitCount(0L);
        book.setWordCount(0L);
        book.setCommentCount(0L);
        book.setCreateTime(LocalDateTime.now().toString());
        book.setUpdateTime(LocalDateTime.now().toString());

        bookMapper.insert(book);
    }

    @Override
    public void deleteBook(Long id) {
        bookMapper.deleteById(id);
    }

    @Override
    public void updateBook(BookInfo info) {
        Book book = new Book();
        book.setId(info.getId());
        book.setPicUrl(info.getPicUrl());
        book.setBookName(info.getBookName());
        book.setCategoryId(info.getCategoryId());
        book.setCategoryName(info.getCategoryName());
        book.setBookDesc(info.getBookDesc());
        book.setState(info.getState());
        book.setBookState(info.getBookState());
        book.setUpdateTime(LocalDateTime.now().toString());

        bookMapper.updateById(book);
    }

    @Override
    public List<BookInfo> queryAll() {
        QueryWrapper<Book> wrapper = new QueryWrapper<>();
        List<Book> books = bookMapper.selectList(wrapper);
        List<BookInfo> infos = books.stream().map(entity -> {
            BookInfo bookInfo = getBookInfo(entity);

            return bookInfo;
        }).collect(Collectors.toList());

        return infos;
    }

    @Override
    public List<BookInfo> queryByAuthorId(Long authorId) {
        QueryWrapper<Book> wrapper = new QueryWrapper<>();
        List<Book> entities = bookMapper.selectList(wrapper.eq("author_id", authorId));

        List<BookInfo> infos = entities.stream().map(entity -> {
            BookInfo bookInfo = getBookInfo(entity);
            return bookInfo;
        }).collect(Collectors.toList());

        return infos;
    }

    @Override
    public List<BookInfo> queryByBookId(Long categoryId) {
        QueryWrapper<Book> wrapper = new QueryWrapper<>();
        wrapper.eq("category_id", categoryId);
        List<Book> books = bookMapper.selectList(wrapper);
        List<BookInfo> infos = books.stream().map(entity -> {
            BookInfo bookInfo = getBookInfo(entity);


            return bookInfo;
        }).collect(Collectors.toList());

        return infos;
    }

    private BookInfo getBookInfo(Book entity) {
        if (entity == null){
            return null;
        }
        BookInfo bookInfo = new BookInfo();
        bookInfo.setId(entity.getId());
        bookInfo.setPicUrl(entity.getPicUrl());
        bookInfo.setBookName(entity.getBookName());
        bookInfo.setAuthorId(entity.getAuthorId());
        bookInfo.setAuthorName(entity.getAuthorName());
        bookInfo.setChannel(entity.getChannel());
        bookInfo.setCategoryId(entity.getCategoryId());
        Category category = categoryMapper.selectById(entity.getCategoryId());
        if (null != category) {
            bookInfo.setCategoryName(category.getName());
        }
        bookInfo.setBookDesc(entity.getBookDesc());
        bookInfo.setScore(entity.getScore());
        bookInfo.setState(entity.getState());
        bookInfo.setBookState(entity.getBookState());
        bookInfo.setVisitCount(entity.getVisitCount());
        bookInfo.setWordCount(entity.getWordCount());
        bookInfo.setCommentCount(entity.getCommentCount());
        bookInfo.setLastIndexId(entity.getLastIndexId());
        bookInfo.setLastIndexUpdateTime(DateUtil.format(entity.getLastIndexUpdateTime()));
        bookInfo.setCreateTime(DateUtil.format(entity.getCreateTime()));
        bookInfo.setUpdateTime(DateUtil.format(entity.getUpdateTime()));
        bookInfo.setLastIndexName(entity.getLastIndexName());

        return bookInfo;
    }
}
